home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume11 / zoo / part01 next >
Encoding:
Internet Message Format  |  1987-08-16  |  46.8 KB

  1. Path: uunet!rs
  2. From: rs@uunet.UU.NET (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v11i010:  File archiver programe, Part01/07
  5. Message-ID: <965@uunet.UU.NET>
  6. Date: 18 Aug 87 01:59:25 GMT
  7. Organization: UUNET Communications Services, Arlington, VA
  8. Lines: 1520
  9. Approved: rs@uunet.UU.NET
  10.  
  11. Submitted-by: iuvax!bsu-cs!dhesi@seismo.CSS.GOV (Rahul Dhesi)
  12. Posting-number: Volume 11, Issue 10
  13. Archive-name: zoo/Part01
  14.  
  15. This is part 1 of 7 of the source distribution of zoo 1.51.
  16.  
  17. The zoo archiver provides most of the functionality of the utilities
  18. "tar" and "cpio" with some restrictions (file protections and
  19. multiple links are not currently preserved and archives cannot be
  20. read from standard input or sent to standard ouput); in addition, it
  21. supports storage of files in compressed form.  Long filenames of up
  22. to 255 characters can be handled.
  23.  
  24. #!/bin/sh
  25. # This is a shell archive, meaning:
  26. # 1. Remove everything above the #! /bin/sh line.
  27. # 2. Save the resulting text in a file.
  28. # 3. Execute the file with /bin/sh (not csh) to create:
  29. #    Bugs
  30. #    Changes
  31. #    Copyright
  32. #    Install
  33. #    addbfcrc.c
  34. #    addfname.c
  35. #    assert.h
  36. #    basename.c
  37. #    bsd.c
  38. #    comment.c
  39. #    crcdefs.c
  40. #    debug.h
  41. #    errors.i
  42. #    fiz.c
  43. #    generic.c
  44. #    getfile.c
  45. export PATH; PATH=/bin:/usr/bin:$PATH
  46. if test -f 'Bugs'
  47. then
  48.     echo shar: "will not over-write existing file 'Bugs'"
  49. else
  50. sed 's/^X//' << \SHAR_EOF > 'Bugs'
  51. X
  52. X                               KNOWN BUGS
  53. X
  54. XThis is a summary of known bugs in zoo version 1.51.
  55. X
  56. X   - Attempted creation of a directory with a name of nearly 255
  57. X     characters in length may fail.  This bug was deduced from an
  58. X     inspection of the code, and no attempt has yet been made to confirm
  59. X     it in practice or fix it.
  60. X
  61. X
  62. X                                     -- Rahul Dhesi 1987/07/12
  63. SHAR_EOF
  64. fi
  65. if test -f 'Changes'
  66. then
  67.     echo shar: "will not over-write existing file 'Changes'"
  68. else
  69. sed 's/^X//' << \SHAR_EOF > 'Changes'
  70. X
  71. X
  72. X                                CHANGES
  73. X
  74. X
  75. XThis is a summary of changes from Zoo version 1.41 to version 1.51.
  76. X
  77. X   - Zoo 1.41 always deleted an archived file if another file with the
  78. X     same name was added to the archive, even if the two files had
  79. X     different directory prefixs.  Zoo 1.51 works as follows.  If Zoo is
  80. X     storing full pathnames during addition, then it deletes the old
  81. X     file only if the old and new files have identical pathnames.  If
  82. X     Zoo is not storing pathnames but only filenames, then it deletes
  83. X     the old file if the old and new files have the same filename,
  84. X     regardless of their pathnames.
  85. X
  86. X   - If a supplied argument matches no files, Zoo will now give an error
  87. X     message.  Previous versions gave an error message only if no files
  88. X     matched any argument.  However, this does not currently affect the
  89. X     status code returned on exit.
  90. X
  91. X   - Zoo 1.41 did not archive a file whose filename (without path
  92. X     prefix) was the same as the name of a subdirectory in the current
  93. X     directory.   Similarly an archive of the form "xyz.zoo" was ignored
  94. X     by the list command if a subdirectory "xyz" existed in the current
  95. X     directory.  This bug is now fixed.
  96. X
  97. X   - Wildcard handling is now uniform across all operating systems.  "*"
  98. X     matches zero or more characters and "?" matches any one character.
  99. X     The dot is no longer special.  Thus "zoo a xyz *" will always add
  100. X     all files to archive xyz.zoo on all systems.
  101. X
  102. X   - The new switch 'I' causes Zoo to read names of files to be archived
  103. X     from standard input.
  104. X
  105. X   - The Novice commands no longer store the directory prefix for any
  106. X     filename.  Thus Zoo's Novice commands simulate the behavior of
  107. X     other archive programs.
  108. X
  109. X   - A bug was fixed that had caused the file date and time not to be
  110. X     restored when full path was restored.
  111. X
  112. X   - A bug was fixed that had caused the directory prefix not to be
  113. X     saved when a filename had no dot in it but directory prefix
  114. X     contained a dot.
  115. X
  116. X   - A bug was fixed that had caused the totals line to be corrupted in
  117. X     the "La" command.
  118. X
  119. X   - Packing now keeps the archive in the same directory.  Users with
  120. X     limited disk space can still pack an archive from one disk to
  121. X     another by using the . switch.
  122. X
  123. X   - A bug related to incorrect handling of timezones, when daylight
  124. X     savings is in effect, was fixed.
  125. X
  126. X
  127. X                                     -- Rahul Dhesi 1987/07/12
  128. SHAR_EOF
  129. fi
  130. if test -f 'Copyright'
  131. then
  132.     echo shar: "will not over-write existing file 'Copyright'"
  133. else
  134. sed 's/^X//' << \SHAR_EOF > 'Copyright'
  135. X
  136. X                            COPYRIGHT
  137. X
  138. X
  139. XCertain rules apply to the distribution of the Zoo archiver.
  140. X
  141. XThe following rules apply only to the zoo archiver itself.
  142. XCurrently, all extract-only programs, and all supporting utili-
  143. Xties, are fully in the public domain and are expected to remain so
  144. Xfor the forseeable future.
  145. X
  146. X"This program" refers to version 1.50 and separately to each sub-
  147. Xsequent version of the Zoo archiver and to all derivative works
  148. Xthereof.  "Distribution right" refers to any copyright, compila-
  149. Xtion copyright, license, or other right to control distribution or
  150. Xcopying.  "Compiled code" refers to software that can be executed
  151. Xby a computer system.
  152. X
  153. XThis program is copyrighted but its distribution for noncommercial
  154. Xpurposes is permitted, with the following restrictions.
  155. X
  156. X   - You are prohibited from distributing this program as part of
  157. X     any package over which you claim a distribution right.  This
  158. X     restriction does not apply if any distribution right is
  159. X     claimed only over individual items that you own or for which
  160. X     the distribution right has been explicitly assigned to you,
  161. X     and not over the package as a collection.
  162. X
  163. X   - You are prohibited from making this program available for
  164. X     downloading via telecommunications if you charge a total of
  165. X     more than $7.00 per hour at 1200 bps.
  166. X
  167. X   - You are prohibited from distributing this program as compiled
  168. X     code unless you also distribute the source code from which
  169. X     the compiled code was derived.  This restriction does not
  170. X     apply if the compiled code was created by me.
  171. X
  172. X   - You are prohibited from creating, from this program, any
  173. X     derivative work over which you claim a distribution right.
  174. X
  175. XThe above restrictions may be relaxed by special agreement;
  176. Xplease contact me for details.
  177. X
  178. X                              -- Rahul Dhesi 1987/07/12
  179. X                                 UUCP:    iuvax!bsu-cs!dhesi or
  180. X                                          pur-ee!bsu-cs!dhesi
  181. X                                 GEnie:   DHESI
  182. X                                 Plink:   OLS806
  183. X                                 Phone:   +1 317 285 8641 daytime EST
  184. X                                 US mail: 720 W. Centennial Ave #15,
  185. X                                          Muncie, Indiana 47303
  186. SHAR_EOF
  187. fi
  188. if test -f 'Install'
  189. then
  190.     echo shar: "will not over-write existing file 'Install'"
  191. else
  192. sed 's/^X//' << \SHAR_EOF > 'Install'
  193. X
  194. X                              INSTALLATION
  195. X
  196. X
  197. XThis document explains how to compile and install the zoo archiver.
  198. X
  199. XGenerally, you will not build zoo by directly invoking the supplied
  200. Xmakefile.  Instead, you will execute one of the supplied scripts, or
  201. Xcreate a suitable script.  Each supplied script has a name beginning
  202. Xwith the characters "mk" and is executed with the command
  203. X"sh scriptname" or "csh scriptname".  All the scripts listed below
  204. Xworked correctly with version 1.50 of zoo, which was given only limited
  205. Xdistribution.  The current version 1.51 differs from 1.50 only in the
  206. Xfiles bsd.c, sysv.c, and version.c, so I expect the scripts to still
  207. Xwork, with one exception that is noted.  The following scripts are sup-
  208. Xplied.
  209. X
  210. Xmksysv    This is for any system running System V Release 2 or something
  211. X          reasonably compatible.  It is known to work on the *T&T **IX
  212. X          PC (also known as the 3B1 or the *T&T 7300) running software
  213. X          revision 3.0.  It will also work on more recent versions of
  214. X          Xenix.  On older machine architectures this script may need to
  215. X          be revised to add a `-Ml' switch or equivalent to cause the
  216. X          large memory model to be used.  For Microport System V/AT and
  217. X          Xenix see also descriptions for mkuport, mkx86, and mkx68.
  218. X
  219. Xmkbsd     This is for 4.3BSD.  It is known to work on a VAX-11/785 run-
  220. X          ning 4.3BSD straight from Berkeley.
  221. X
  222. Xmkuport   For Microport System V/AT.  This script includes the -Ml
  223. X          switch so that the large memory model is used.
  224. X
  225. Xmksysvsh  This script first calls mksysv to build zoo, then it deletes
  226. X          the executable program and re-loads it using the shareable
  227. X          libraries available on the *T&T **IX PC.  It used to work but
  228. X          I'm given to understand that it was broken by a reference to a
  229. X          timezone-related variable that is absent from the shared
  230. X          library.
  231. X
  232. Xmkx68     This script is for Xenix/68000.  It is known to work on a
  233. X          Radio Shack Model 16 running Xenix version 3.01.01.  It takes
  234. X          care of problems in the C compiler and in the include files
  235. X          related to incorrect handling of the `void' data type.  How-
  236. X          ever, since this version of Xenix does not have the memset()
  237. X          library function, the line "#define MEMSET" must first be com-
  238. X          mented out from the group of symbol definitions for SYS_V in
  239. X          the file ``options.h''.
  240. X
  241. Xmkx86     This script is for Xenix for 80286 systems.  It is known to
  242. X          work on an Intel 310/286 running Xenix 3.4 and an AT running
  243. X          SCO Xenix 2.2.  It causes the large memory model to be used
  244. X          and sufficient stack space to be allocated at load time.
  245. X
  246. XThe file ``options.h'' defines preprocessor symbols for the various sys-
  247. Xtems.  In most cases, given a reasonably powerful C compiler and
  248. Xlibrary, you will be able to find a combination of options that will
  249. Xwork.
  250. X
  251. XOther machine-dependent code and definitions are in machine.h,
  252. Xmachine.c, and portable.h.  Also, the amount of memory used for various
  253. Xarrays can be customized by defining symbols that are described and used
  254. Xin zoomem.h.
  255. X
  256. XThe low-level input/output routines are in portable.c.  In most cases
  257. Xthese will not need to be modified.
  258. X
  259. XThe zoo source code largely conforms to the requirements of Kernighan
  260. Xand Ritchie's book.  Some exceptions are as follows.
  261. X
  262. X   - Variables are unique in their initial 8 characters.  Systems that
  263. X     distinguish fewer than 8 initial characters are currently not sup-
  264. X     ported.
  265. X
  266. X   - Zoo code assumes that members of structures do not have global
  267. X     scope.
  268. X
  269. X   - Long preprocessor symbols are occasionally used.
  270. X
  271. XTROUBLESHOOTING.
  272. X
  273. XThe zoo code uses strchr and strrchr, which are present on System V,
  274. X4.3BSD, and Xenix, but may not be present on 4.2BSD. To get around this,
  275. Xadd the C compiler switches "-Dstrchr=index" and "-Dstrrchr=rindex" to
  276. Xthe make script or to the makefile.
  277. X
  278. XOptionally zoo can use the access() system call to check for file
  279. Xexistence (see the definition for the symbol EXISTS in options.h).
  280. XThere is some question about the appropriatenes of this, because
  281. Xaccess() can give the wrong answer when used from a set-user-id program.
  282. XIf EXISTS is left undefined, zoo uses its own function to test for file
  283. Xexistence by trying to open the file for read and also for write.
  284. X
  285. XTwo common reasons for crashes when zoo is executed are the following.
  286. X
  287. X   - On machines with older (Intel-style) architectures zoo requires the
  288. X     large memory model.  Compiling with the small memory model will
  289. X     cause problems.  Also, systems that are limited to 64 kilobytes of
  290. X     data and 64 kilobytes of code are not currently supported (but they
  291. X     will be in the future).  Note that a small and memory-efficient
  292. X     extract-only program, described below, is separately available that
  293. X     should run on any system with a reasonable C compiler.
  294. X
  295. X   - Generous amounts of stack space is needed.  Depending on the sys-
  296. X     tem, this will vary from about 15 kilobytes to about 33 kilobytes.
  297. X     On systems that cannot expand the stack dynamically you will need
  298. X     to specify the size of the stack area at load time.
  299. X
  300. XSPECIAL VERSIONS.  A version (currently 1.50) is available for MS-DOS
  301. Xthat provides better performance due to assembly language routines and
  302. Xalso includes some system-dependent features.  Another version
  303. X(currently 1.42b) has been ported by J. Brian Waters for the Amiga.  It
  304. Xincludes several AmigaDOS-dependent features such as preservation of
  305. Xfile times and wildcard expansion.
  306. X
  307. XEXTRACT-ONLY VERSIONS.  For a new system, your first concern should be
  308. Xthe ability to extract and list zoo archives.  For this purpose try com-
  309. Xpiling booz (which stands for Barebones Ooz) (currently version 1.01),
  310. Xwhich can be compiled with three different options requiring different
  311. Xdegrees of compiler sophistication and offering different levels of
  312. Xfeatures.  Unlike zoo, booz will work on systems with less than 64 kilo-
  313. Xbytes of total available memory.  Also available, for VAX/VMS, is the
  314. Xextract-only program vooz 1.00.  (Because of serious bugs in the VAX/VMS
  315. Xinput/output routines, the full zoo archiver does not currently work
  316. Xunder VAX/VMS.  Unfortunately, DEC documents these bugs as features, so
  317. Xthey are unlikely to be fixed soon.  I hope to be eventually able to
  318. Xwork around these bugs.)
  319. X
  320. XMachine-dependencies.
  321. X
  322. X   - Currently the only systems supported are those that can read and
  323. X     write in 8-bit units.  The file ``machine.h'' contains a typedef of
  324. X     BYTE, and it must be defined to be an 8-bit quantity.
  325. X
  326. X   - It is not known whether zoo code as it stands will work on a 1's-
  327. X     complement machine.
  328. X
  329. X   - The code assumes that type `int' is at least 16 bits long and type
  330. X     `long' is at least 32 bits long.  (The code may work if type `long'
  331. X     is somewhat smaller than 32 bits but this has not been confirmed.)
  332. X     There may be some implicit assumptions that type `char' is exactly
  333. X     8 bits;  I am not sure if this is so.  However, type `BYTE' must be
  334. X     exactly 8 bits long.
  335. X
  336. X   - In accordance with K&R (p 126), zoo code assumes that sizeof(char)
  337. X     equals exactly 1.
  338. X
  339. X                                     -- Rahul Dhesi 1987/07/12
  340. SHAR_EOF
  341. fi
  342. if test -f 'addbfcrc.c'
  343. then
  344.     echo shar: "will not over-write existing file 'addbfcrc.c'"
  345. else
  346. sed 's/^X//' << \SHAR_EOF > 'addbfcrc.c'
  347. X#ifndef LINT
  348. Xstatic char sccsid[]="@(#) addbfcrc.c 1.2 87/05/03 16:00:26";
  349. X#endif /* LINT */
  350. X
  351. X#include "options.h"
  352. X/*
  353. Xaddbfcrc() accepts a buffer address and a count and adds the CRC for
  354. Xall bytes in the buffer to the global variable crccode using
  355. XCRC-16.
  356. X
  357. XCRC computation algorithm taken from source code for ARC 5.12, which
  358. Xin turn took it from an article by David Schwaderer in the April 1985
  359. Xissue of PC Tech Journal.
  360. X
  361. XI claim no copyright over the contents of this file.
  362. X
  363. X                                    -- Rahul Dhesi 1986/12/31
  364. X
  365. X*/
  366. X
  367. Xextern unsigned int crccode;
  368. Xextern unsigned crctab[];
  369. X
  370. Xvoid addbfcrc(buffer,count)
  371. Xchar *buffer;
  372. Xint count;
  373. X
  374. X{
  375. X   register unsigned int localcrc;
  376. X   register int i;
  377. X   localcrc = crccode;
  378. X
  379. X   for (i=0; i<count; i++)
  380. X      localcrc = (localcrc>>8) ^ crctab[(localcrc ^ (buffer[i])) & 0x00ff];
  381. X   crccode = localcrc;
  382. X}
  383. X
  384. SHAR_EOF
  385. fi
  386. if test -f 'addfname.c'
  387. then
  388.     echo shar: "will not over-write existing file 'addfname.c'"
  389. else
  390. sed 's/^X//' << \SHAR_EOF > 'addfname.c'
  391. X#ifndef LINT
  392. Xstatic char sccsid[]="@(#) addfname.c 1.5 87/05/03 16:00:28";
  393. X#endif /* LINT */
  394. X
  395. X/*
  396. XCopyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
  397. X*/
  398. X#include "options.h"
  399. X
  400. X/* Adds a filename to global list.  (This global list will eventually
  401. Xbe searched by the inlist() function.)  The second through fourth 
  402. Xparameters suppplied are stored with the name of the file and 
  403. Xreturned by inlist. */
  404. X
  405. X#include <stdio.h>
  406. X#include "various.h"
  407. X#include "zoo.h"
  408. X#include "zoofns.h"
  409. X#include "zoomem.h" /* to get LIST_SIZE */
  410. X
  411. Xstatic struct item *fentry[LIST_SIZE];
  412. Xstatic int lastname = 0;                  /* index of last name */
  413. X
  414. Xstruct item {              /* global filename list entry */
  415. X   char *fname;
  416. X   long position;
  417. X   unsigned int date;
  418. X   unsigned int time;
  419. X};
  420. X
  421. Xvoid addfname(fname,position,date,time)
  422. Xchar *fname;
  423. Xlong position;
  424. Xunsigned int date, time;
  425. X{
  426. X   if (lastname == 0)
  427. X      fentry[lastname] = (struct item *) emalloc (sizeof(struct item));
  428. X
  429. X   /* keep a few empty spaces at end to avoid off by one errors */
  430. X   if (lastname >= LIST_SIZE - 3)
  431. X      memerr();
  432. X
  433. X   fentry[lastname]->fname = strdup(fname);
  434. X   fentry[lastname]->position = position;
  435. X   fentry[lastname]->date = date;
  436. X   fentry[lastname]->time = time;
  437. X   lastname++;
  438. X   /* allocate memory for empty entry at end */
  439. X   fentry[lastname] = (struct item *) emalloc (sizeof(struct item)); 
  440. X} /* addfname */
  441. X
  442. X/* inlist() */
  443. X/* Examines global list built by addfname() to see if supplied filename
  444. Xis in the list.  
  445. X
  446. XIf found, returns the file's position within the archive as the function 
  447. Xvalue and the date and time as parameters.  If not found, returns -1.
  448. X
  449. XA simple sequential search is done.
  450. X
  451. XIf justname is nonzero, then the search is for the filename only
  452. Xwithout the directory prefix;  else it is for the full
  453. Xpathname.
  454. X*/
  455. X
  456. Xlong inlist (fname, date, time, justname)
  457. Xchar *fname;
  458. Xunsigned int *date, *time;
  459. Xint justname;
  460. X{
  461. X   register int i = 0;
  462. X    if (justname)
  463. X        fname = nameptr (fname);                    /* if directory wanted */
  464. X   fentry[lastname]->fname = fname;          /* sentinel */
  465. X
  466. X#ifdef IGNORECASE
  467. X#define    COMPARE    strcmpi
  468. X#else
  469. X#define    COMPARE    strcmp
  470. X#endif
  471. X
  472. X   while (COMPARE(fname, 
  473. X                (justname ? nameptr (fentry[i]->fname) : fentry[i]->fname)) != 0) {
  474. X      i++;
  475. X   }
  476. X
  477. X   if (i == lastname)
  478. X      return (-1L);
  479. X   else {
  480. X      *date = fentry[i]->date;
  481. X      *time = fentry[i]->time;
  482. X      return (fentry[i]->position);
  483. X   }
  484. X} /* inlist() */
  485. X
  486. SHAR_EOF
  487. fi
  488. if test -f 'assert.h'
  489. then
  490.     echo shar: "will not over-write existing file 'assert.h'"
  491. else
  492. sed 's/^X//' << \SHAR_EOF > 'assert.h'
  493. X/* @(#) assert.h 1.2 87/05/03 16:00:32 */
  494. X
  495. X/*
  496. XThe contents of this file are hereby released to the public domain.
  497. X
  498. X                           -- Rahul Dhesi 1986/11/14
  499. X
  500. XDefines a macro assert() that causes an assertion error if the assertion
  501. Xfails.  For some useful information about this see "Reliable Data
  502. XStructures in C" by Thomas Plum page 1-21.
  503. X
  504. XConditional compilation:
  505. X
  506. X   If NDEBUG is defined then
  507. X      assert() is defined as null so all assertions vanish
  508. X   else
  509. X      if DUMB_ASS is defined then   -- use dumb assertions
  510. X         assertions print a message but not the filename and line number
  511. X      else
  512. X         assertions print message including filename and line number
  513. X      endif
  514. X   endif
  515. X
  516. XNote:
  517. X   DUMB_ASS should be defined if the preprocessor does not support the 
  518. X   varying constants __FILE__ and __LINE__, which are supposed to hold the 
  519. X   name of the current file and the number of the current line.
  520. X
  521. X*/
  522. X
  523. X#ifndef NDEBUG
  524. X/* assert() macro defined only if NDEBUG is undefined */
  525. X#ifdef DUMB_ASS
  526. X#define assert(E) \
  527. X   { if (!(E)) \
  528. X      prterror ('w', "Assertion error.\n"); \
  529. X   }
  530. X#else
  531. X/* else not DUMB_ASS */
  532. X#define assert(E) \
  533. X   { if (!(E)) \
  534. X      prterror ('w',"Assertion error in %s:%d.\n", __FILE__, __LINE__); \
  535. X   }
  536. X#endif /* not DUMB_ASS */
  537. X#else
  538. X/* else NDEBUG */
  539. X#define assert(E)
  540. X#endif /* NDEBUG */
  541. SHAR_EOF
  542. fi
  543. if test -f 'basename.c'
  544. then
  545.     echo shar: "will not over-write existing file 'basename.c'"
  546. else
  547. sed 's/^X//' << \SHAR_EOF > 'basename.c'
  548. X#ifndef LINT
  549. Xstatic char sccsid[]="@(#) basename.c 1.4 87/05/29 12:53:28";
  550. X#endif /* LINT */
  551. X
  552. X/*
  553. XCopyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
  554. X*/
  555. X
  556. X#include "zoo.h"
  557. X#include "options.h"
  558. X#include "parse.h"
  559. X#include <stdio.h>
  560. X#include "various.h"
  561. X#include "zoofns.h"
  562. X#include "debug.h"
  563. X#include "assert.h"
  564. X
  565. X/* This function strips device/directory information from
  566. Xa pathname and returns just the plain filename */
  567. Xvoid basename (pathname, fname)
  568. Xchar *pathname;
  569. Xchar fname[];
  570. X{
  571. X   strcpy (fname, nameptr (pathname));
  572. X}
  573. X
  574. X/* Set of legal MSDOS filename characters.  The working of cvtchr() depends
  575. Xon the order of the first few characters here.  In particular, '_' is
  576. Xpositioned so '.' gets converted to it. */
  577. Xstatic char legal[] = 
  578. X"tabcdefghijklmnopqrs_uvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ@^`{}~!#$%&'()-";
  579. X
  580. X/****************
  581. Xcvtchr() converts a character to a lowercase alphabetic character in
  582. Xa somewhat random way.  
  583. X*/
  584. X#define  cvtchr(ch)        legal[(ch & 0xff) % 26]
  585. X
  586. X/***************
  587. Xcleanup() cleans up a string so it contains only legal MSDOS filename
  588. Xcharacters.  Any other characters are converted to an underscore.
  589. XIf the filename is null or if it begins with a dot, it is fixed.
  590. XAll dots are also converted.
  591. X*/
  592. Xvoid cleanup (p)
  593. Xchar *p;
  594. X{
  595. X   assert(p != NULL);
  596. X   if (*p == '\0')
  597. X      strcpy (p, "X");
  598. X   if (*p == '.')
  599. X      *p = '_';
  600. X   while (*p != '\0') {
  601. X      if (strchr (legal, *p) == NULL) {   /* if invalid character */
  602. X         *p = cvtchr(*p);
  603. X      }
  604. X      p++;
  605. X   }
  606. X}
  607. X/* This function strips device/directory information from a pathname,
  608. Xforces the remaining filename to MSDOS format, and returns it.  Any
  609. Xillegal characters are fixed.
  610. X*/
  611. Xvoid dosname (pathname, fname)
  612. Xchar *pathname;
  613. Xchar fname[];
  614. X{
  615. X   struct path_st path_st;
  616. X   parse (&path_st, pathname);
  617. X   strcpy (fname, path_st.fname);
  618. X   cleanup (fname);
  619. X   if (path_st.ext[0] != '\0') {
  620. X      strcat (fname, ".");
  621. X      cleanup (path_st.ext);
  622. X      strcat (fname, path_st.ext);
  623. X   }
  624. X}
  625. X
  626. X/* 
  627. XThis function accepts a pathname and returns the extension.  If there is
  628. Xnone, it returns a null string
  629. X*/
  630. X
  631. Xvoid extension (pathname, ext)
  632. Xchar *pathname;
  633. Xregister char ext[];
  634. X{
  635. X   struct path_st path_st;
  636. X   parse (&path_st, pathname);
  637. X   strcpy (ext, path_st.ext);
  638. X}
  639. X
  640. X/* rootname() */
  641. X/* Accepts a pathname.  Returns the root filename, i.e., with both the
  642. Xdirectory path and the extension stripped. */
  643. X
  644. Xvoid rootname (path, root)
  645. Xchar *path, *root;
  646. X{
  647. X   char *p;
  648. X   static char dot[] = {EXT_CH, '\0'};
  649. X   strcpy(root, nameptr(path));           /* copy all but path prefix */
  650. X   p = findlast(root, dot);               /* find last dot */
  651. X   if (p != NULL)                         /* if found ... */
  652. X      *p = '\0';                          /* ... null it out */
  653. X}
  654. X
  655. X/* nameptr() */
  656. X/* Accepts a pathname.  Returns a pointer to the filename within
  657. Xthat pathname.
  658. X*/
  659. X
  660. Xchar *nameptr (path)
  661. Xchar *path;
  662. X{
  663. X   char *t;
  664. X   t = findlast (path, PATH_SEP);   /* last char separating device/directory */
  665. X   debug ((printf ("nameptr:  findlast returned ptr to string [%s].\n",t)))
  666. X   if (t == NULL)                /* no separator */
  667. X      return (path);
  668. X   else {
  669. X      return (t+1);
  670. X   }
  671. X}
  672. SHAR_EOF
  673. fi
  674. if test -f 'bsd.c'
  675. then
  676.     echo shar: "will not over-write existing file 'bsd.c'"
  677. else
  678. sed 's/^X//' << \SHAR_EOF > 'bsd.c'
  679. X#ifndef LINT
  680. Xstatic char bsdid[]="@(#) bsd.c 1.4 87/07/12 15:05:42";
  681. X#endif /* LINT */
  682. X
  683. X/* machine.c for 4.3BSD. */
  684. X
  685. X/*
  686. XThe contents of this file are hereby released to the public domain.
  687. X
  688. X                                    -- Rahul Dhesi  1986/12/31
  689. X*/
  690. X
  691. Xlong tell();
  692. X
  693. X/****************
  694. Xfunction trunc() truncates a file.
  695. X*/
  696. X
  697. Xint trunc (handle)
  698. Xint handle;
  699. X{
  700. X   ftruncate (handle, tell(handle));
  701. X}
  702. X
  703. X/****************
  704. XFunction fixfname() converts the supplied filename to a syntax
  705. Xlegal for the host system.  It is used during extraction.
  706. X*/
  707. X
  708. Xchar *fixfname(fname)
  709. Xchar *fname;
  710. X{
  711. X   return (fname); /* default is no-op */
  712. X}
  713. X
  714. X/****************
  715. XDate and time functions are standard UNIX-style functions.  "nixtime.i"
  716. Xwill be included by machine.c.
  717. X*/
  718. X
  719. X#include <sys/types.h>
  720. X#include <sys/stat.h>
  721. X#include <sys/time.h>
  722. X
  723. X/* Function isadir() returns 1 if the supplied handle is a directory, 
  724. Xelse it returns 0.  
  725. X*/
  726. X
  727. Xint isadir (handle)
  728. Xint handle;
  729. X{
  730. X   struct stat buf;           /* buffer to hold file information */
  731. X   if (fstat (handle, &buf) == -1) {
  732. X      return (0);             /* inaccessible -- assume not dir */
  733. X   } else {
  734. X      if (buf.st_mode & S_IFDIR)
  735. X         return (1);
  736. X      else
  737. X         return (0);
  738. X   }
  739. X}
  740. X
  741. X/* Function gettz(), returns the offset from GMT in seconds */
  742. Xlong gettz()
  743. X{
  744. X   struct timeval tp;
  745. X   struct timezone tzp;
  746. X   gettimeofday (&tp, &tzp);              /* specific to 4.3BSD */
  747. X
  748. X   /* return (tzp.tz_minuteswest * 60); */ /* old incorrect code fixed below */
  749. X    /*
  750. X    Timezone fix thanks to Bill Davidsen <wedu@ge-crd.ARPA>
  751. X    {uunet | philabs | seismo!rochester}!steinmetz!crdos1!davidsen
  752. X    */
  753. X   return (tzp.tz_minuteswest * 60 - tzp.tz_dsttime * 3600L);
  754. X}
  755. X
  756. X/* Standard UNIX-compatible time routines */
  757. X#include "nixtime.i"
  758. SHAR_EOF
  759. fi
  760. if test -f 'comment.c'
  761. then
  762.     echo shar: "will not over-write existing file 'comment.c'"
  763. else
  764. sed 's/^X//' << \SHAR_EOF > 'comment.c'
  765. X#ifndef LINT
  766. Xstatic char sccsid[]="@(#) comment.c 1.5 87/05/29 12:53:35";
  767. X#endif /* LINT */
  768. X
  769. X/*
  770. XCopyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
  771. X*/
  772. X
  773. X#include "options.h"
  774. X#include "portable.h"
  775. X/* comment() */
  776. X/* Updates comments */
  777. X
  778. X/* buffer size for any one comment line */
  779. X#define  COMMENT_LINE_SIZE 77
  780. X
  781. X#define  MAX_COMMENT_SIZE  65535
  782. X#include <stdio.h>
  783. X#include "various.h"
  784. X
  785. X#ifndef NOSIGNAL
  786. X#include <signal.h>
  787. X#endif
  788. X
  789. X#include "zoo.h"
  790. X#include "zoofns.h"
  791. X#include "errors.i"
  792. X
  793. X#ifdef LINT_ARGS
  794. Xvoid show_comment (struct direntry *, FILE *, int, char *);
  795. Xget_comment (struct direntry *, FILE *, char *);
  796. X#else
  797. Xvoid show_comment ();
  798. Xget_comment ();
  799. X#endif
  800. X
  801. Xvoid comment(zoo_path, option)
  802. Xchar *zoo_path, *option;
  803. X{
  804. X#ifndef NOSIGNAL  
  805. Xint (*oldsignal)();
  806. X#endif
  807. XFILE *zoo_file;                           /* stream for open archive */
  808. Xlong next_ptr;                            /* pointers to within archive */
  809. Xlong this_dir_offset;                     /* pointers to within archive */
  810. Xstruct direntry direntry;                 /* directory entry */
  811. Xstruct zoo_header zoo_header;
  812. Xint matched = 0;                          /* any files matched? */
  813. Xunsigned int zoo_date, zoo_time;          /* for restoring archive timestamp */
  814. X
  815. X/* on entry option points to first letter */
  816. X++option;
  817. Xif (*option != '\0')
  818. X   prterror ('f', inv_option, *option);
  819. X
  820. Xif ((zoo_file = fopen (zoo_path, FRWSTR)) == NULL)
  821. X   prterror ('f', could_not_open, zoo_path);
  822. X
  823. X/* save archive timestamp */
  824. X#ifdef GETUTIME
  825. Xgetutime (zoo_path, &zoo_date, &zoo_time);
  826. X#else
  827. Xgettime (fileno(zoo_file), &zoo_date, &zoo_time);
  828. X#endif
  829. X
  830. X/* read header and rewrite with updated version numbers */
  831. Xrwheader (&zoo_header, zoo_file);
  832. X
  833. X/* Loop through and add comments for matching files */
  834. Xwhile (1) {
  835. X   this_dir_offset = ftell (zoo_file);    /* save pos'n of this dir entry */
  836. X   readdir (&direntry, zoo_file, 1);      /* read directory entry */
  837. X   next_ptr = direntry.next;              /* ptr to next dir entry */
  838. X
  839. X   /* exit on end of directory chain or end of file */
  840. X   if (next_ptr == 0L || feof(stdin))
  841. X      break;
  842. X
  843. X   /* add comments for matching non-deleted files */
  844. X   if (!direntry.deleted && needed (direntry.fname)) {
  845. X      matched++;
  846. X      show_comment (&direntry, zoo_file, 1, direntry.fname);
  847. X      get_comment (&direntry, zoo_file, direntry.fname);
  848. X      fseek (zoo_file, this_dir_offset, 0);
  849. X#ifndef NOSIGNAL
  850. X      oldsignal = signal (SIGINT, SIG_IGN);
  851. X#endif
  852. X      fwr_dir (&direntry, zoo_file);
  853. X      /* fwrite ((char *) &direntry, sizeof(direntry), 1, zoo_file); */
  854. X#ifndef NOSIGNAL
  855. X      signal (SIGINT, oldsignal);
  856. X#endif
  857. X   }
  858. X   fseek (zoo_file, next_ptr, 0);   /* ..seek to next dir entry */
  859. X} /* end while */
  860. X
  861. X#ifdef NIXTIME
  862. Xfclose (zoo_file);
  863. Xsetutime (zoo_path, zoo_date, zoo_time); /* restore timestamp */
  864. X#else
  865. Xsettime (fileno(zoo_file), zoo_date, zoo_time); /* restore timestamp */
  866. Xfclose (zoo_file);
  867. X#endif
  868. X
  869. Xif (!matched)
  870. X   printf ("Zoo:  %s", no_match);
  871. X} /* comment */
  872. X
  873. X/* show_comment() */
  874. X/* shows comment on screen.  If show=1, says "Current comment is..." */
  875. X
  876. Xvoid show_comment (direntry, zoo_file, show, name)
  877. Xstruct direntry *direntry;
  878. XFILE *zoo_file;
  879. Xint show;
  880. Xchar *name;       /* name of file for which comment is being added */
  881. X{
  882. X   if (direntry->cmt_size != 0) {
  883. X      unsigned int i;
  884. X      char ch;
  885. X      int newline = 1;
  886. X      fseek (zoo_file, direntry->comment, 0);   
  887. X      if (show)
  888. X         printf ("Current comment for %s is:\n", name);
  889. X      for (i = 0; i < direntry->cmt_size; i++) {/* show it */
  890. X         ch = fgetc (zoo_file) & 0x7f;          /* 7 bits only */
  891. X         if (newline)
  892. X            printf (" |");    /* indent and mark comment lines thus */
  893. X         fputchar (ch);
  894. X         if (ch == '\n')
  895. X            newline = 1;
  896. X         else
  897. X            newline = 0;
  898. X      }
  899. X      if (!newline)              /* always terminate with newline */
  900. X         fputchar ('\n');
  901. X   }
  902. X} /* show_comment() */
  903. X
  904. X
  905. X/* get_comment() */
  906. X/* Shows user old comment and updates it */
  907. X
  908. X/* INPUT:
  909. X   direntry points to current directory entry.
  910. X   zoo_file is archive file.
  911. X   this_path is full pathname of file being updated/added.
  912. X
  913. X   OUTPUT:
  914. X   Comment is added to file and supplied directory entry is updated
  915. X   with comment size and seek position but directory entry is
  916. X   not written to file.  Exceptions:  If RETURN is hit as first line,
  917. X   previous comment is left unchanged.  If /END is hit, previous
  918. X   comment is superseded, even if new comment is null.
  919. X*/
  920. X
  921. Xget_comment (direntry, zoo_file, this_path)  /* update comment */
  922. Xregister struct direntry *direntry;
  923. XFILE *zoo_file;
  924. Xchar *this_path;
  925. X{
  926. X   unsigned int line_count = 0;        /* count of new comment lines */
  927. X
  928. X   fseek (zoo_file, 0L, 2);            /* ready to append new comment */
  929. X   fprintf (stderr, "[Enter comment for %s then type /END]\n", this_path);
  930. X   while (1) {
  931. X      char cmt_line[COMMENT_LINE_SIZE];
  932. X      int cmt_size;
  933. X      if (fgets (cmt_line, sizeof(cmt_line), stdin) == NULL)
  934. X         break;
  935. X      line_count++;
  936. X      if (line_count == 1) {                 /* first line typed */
  937. X         if (!strcmp (cmt_line, "\n"))   /* exit if first line blank */
  938. X            break;
  939. X         direntry->comment = ftell (zoo_file);
  940. X         direntry->cmt_size = 0;
  941. X      }
  942. X      if (!strcmpi (cmt_line, "/end\n"))
  943. X         break;
  944. X      cmt_size = strlen (cmt_line);
  945. X      if (MAX_COMMENT_SIZE - direntry->cmt_size > cmt_size) {
  946. X         direntry->cmt_size += (unsigned int) cmt_size;
  947. X         if (fwrite (cmt_line, cmt_size, 1, zoo_file) < 1)
  948. X            prterror ('f', disk_full);
  949. X      }
  950. X   } /* end while */
  951. X} /* get_comment() */
  952. X
  953. SHAR_EOF
  954. fi
  955. if test -f 'crcdefs.c'
  956. then
  957.     echo shar: "will not over-write existing file 'crcdefs.c'"
  958. else
  959. sed 's/^X//' << \SHAR_EOF > 'crcdefs.c'
  960. X#ifndef LINT
  961. Xstatic char sccsid[]="@(#) crcdefs.c 1.2 87/05/03 16:00:46";
  962. X#endif /* LINT */
  963. X
  964. X#include "options.h"
  965. X
  966. X/* Global definitions for CRC calculation, adapted from the source code
  967. Xfor ARC.EXE 5.12.
  968. X
  969. XWHEREAS
  970. X
  971. X   Algorithms cannot be copyrighted;
  972. X   
  973. X   And whereas this table of values, being determined by the needs of the 
  974. X   algorithm and being expressible in no other substantially dissimilar 
  975. X   manner, cannot be copyrighted either;
  976. X
  977. X   And whereas I claim no copyright over the contents of this file;
  978. X
  979. XNOW THEREFORE
  980. X
  981. X   It appears that the contents of this file are in the public domain.
  982. X
  983. X                                 -- Rahul Dhesi
  984. X*/
  985. X
  986. Xunsigned int crccode;
  987. Xunsigned int crctab[] = {
  988. X   0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 0xc601, 
  989. X   0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 0xcc01, 0x0cc0, 
  990. X   0x0d80, 0xcd41, 0x0F00, 0xcFc1, 0xce81, 0x0e40, 0x0a00, 0xcac1, 0xcb81, 
  991. X   0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 0xd801, 0x18c0, 0x1980, 0xd941, 
  992. X   0x1b00, 0xdbc1, 0xda81, 0x1a40, 0x1e00, 0xdec1, 0xdF81, 0x1F40, 0xdd01, 
  993. X   0x1dc0, 0x1c80, 0xdc41, 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 
  994. X   0x1680, 0xd641, 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 
  995. X   0x1040, 0xF001, 0x30c0, 0x3180, 0xF141, 0x3300, 0xF3c1, 0xF281, 0x3240, 
  996. X   0x3600, 0xF6c1, 0xF781, 0x3740, 0xF501, 0x35c0, 0x3480, 0xF441, 0x3c00, 
  997. X   0xFcc1, 0xFd81, 0x3d40, 0xFF01, 0x3Fc0, 0x3e80, 0xFe41, 0xFa01, 0x3ac0, 
  998. X   0x3b80, 0xFb41, 0x3900, 0xF9c1, 0xF881, 0x3840, 0x2800, 0xe8c1, 0xe981, 
  999. X   0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 0xee01, 0x2ec0, 0x2F80, 0xeF41, 
  1000. X   0x2d00, 0xedc1, 0xec81, 0x2c40, 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 
  1001. X   0xe7c1, 0xe681, 0x2640, 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 
  1002. X   0x2080, 0xe041, 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 
  1003. X   0x6240, 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, 
  1004. X   0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaF01, 0x6Fc0, 0x6e80, 0xae41, 0xaa01, 
  1005. X   0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 0x7800, 0xb8c1, 
  1006. X   0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 0xbe01, 0x7ec0, 0x7F80, 
  1007. X   0xbF41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 0xb401, 0x74c0, 0x7580, 0xb541, 
  1008. X   0x7700, 0xb7c1, 0xb681, 0x7640, 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 
  1009. X   0x71c0, 0x7080, 0xb041, 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 
  1010. X   0x5280, 0x9241, 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 
  1011. X   0x5440, 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5F00, 0x9Fc1, 0x9e81, 0x5e40, 
  1012. X   0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 0x8801, 
  1013. X   0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 0x4e00, 0x8ec1, 
  1014. X   0x8F81, 0x4F40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 0x4400, 0x84c1, 0x8581, 
  1015. X   0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 0x8201, 0x42c0, 0x4380, 0x8341, 
  1016. X   0x4100, 0x81c1, 0x8081, 0x4040 
  1017. X};
  1018. X
  1019. SHAR_EOF
  1020. fi
  1021. if test -f 'debug.h'
  1022. then
  1023.     echo shar: "will not over-write existing file 'debug.h'"
  1024. else
  1025. sed 's/^X//' << \SHAR_EOF > 'debug.h'
  1026. X/* @(#) debug.h 1.2 87/05/03 16:00:48 */
  1027. X
  1028. X/* 
  1029. XThe contents of this file are hereby released to the public domain.
  1030. X
  1031. X                           -- Rahul Dhesi 1986/11/14
  1032. X
  1033. Xdefines conditional function calls 
  1034. X
  1035. XUsage:  The statement
  1036. X
  1037. X   debug((printf("y = %d\n", y)))
  1038. X
  1039. Xmay be placed anywhere where two or more statements could be used.  It will 
  1040. Xprint the value of y at that point.
  1041. X
  1042. XConditional compilation:
  1043. X
  1044. X   if DEBUG is defined
  1045. X      define the macro debug(X) to execute statement X
  1046. X   else
  1047. X      define the macro debug(X) to be null
  1048. X   endif
  1049. X*/
  1050. X
  1051. X#ifdef DEBUG
  1052. X#define  debug(x)    x;
  1053. X#else
  1054. X#define  debug(x)
  1055. X#endif
  1056. X
  1057. SHAR_EOF
  1058. fi
  1059. if test -f 'errors.i'
  1060. then
  1061.     echo shar: "will not over-write existing file 'errors.i'"
  1062. else
  1063. sed 's/^X//' << \SHAR_EOF > 'errors.i'
  1064. X/* @(#) errors.i 1.5 87/05/21 11:37:33 */
  1065. X
  1066. X/*
  1067. XThe contents of this file are hereby released to the public domain.
  1068. X
  1069. X                           -- Rahul Dhesi 1986/11/14
  1070. X*/
  1071. X
  1072. X/* defines all the errors as externs.  Declarations must be
  1073. Xequivalent to those in prterror.c */
  1074. X
  1075. X/* These declarations must be equivalent to those in prterror.c */
  1076. Xextern char no_match[];
  1077. Xextern char failed_consistency[];
  1078. Xextern char invalid_header[];
  1079. Xextern char internal_error[];
  1080. Xextern char disk_full[];
  1081. Xextern char bad_directory[];
  1082. Xextern char no_memory[];
  1083. Xextern char too_many_files[];
  1084. X
  1085. X#ifndef OOZ
  1086. Xextern char wrong_version[];
  1087. Xextern char cant_process[];
  1088. Xextern char option_ignored[];
  1089. Xextern char inv_option[];
  1090. Xextern char bad_crc[];
  1091. X#endif
  1092. X
  1093. Xextern char could_not_open[];
  1094. X
  1095. SHAR_EOF
  1096. fi
  1097. if test -f 'fiz.c'
  1098. then
  1099.     echo shar: "will not over-write existing file 'fiz.c'"
  1100. else
  1101. sed 's/^X//' << \SHAR_EOF > 'fiz.c'
  1102. X#ifndef LINT
  1103. Xstatic char sccsid[]="@(#) fiz.c 1.4 87/05/29 12:53:42";
  1104. X#endif /* LINT */
  1105. X
  1106. X/*
  1107. XThe contents of this file are hereby released to the public domain.
  1108. X
  1109. X                                   -- Rahul Dhesi 1987/02/06
  1110. X*/
  1111. X
  1112. X/*
  1113. XSearches for all directory entries in an archive and prints their
  1114. Xoffsets.  Zoo 1.41 and later may then be asked to extract a specific
  1115. Xfile by supplying the offset of the file.
  1116. X*/
  1117. X
  1118. X#include "options.h"
  1119. X#include <stdio.h>
  1120. X#include "various.h"
  1121. X#include "zoofns.h"
  1122. X#include "portable.h"         /* I/O definitions */
  1123. X#include "zoo.h"
  1124. X
  1125. X#ifdef LINT_ARGS
  1126. Xvoid prtctrl (char *);
  1127. Xvoid prtch (unsigned int);
  1128. X#else
  1129. Xvoid prtctrl ();
  1130. Xvoid prtch ();
  1131. X#endif
  1132. X
  1133. Xmain(argc,argv)
  1134. Xregister int argc;
  1135. Xregister char **argv;
  1136. X{
  1137. X   char *zooname;          /* name of archive to be read */
  1138. X   FILE *zoo_file;         /* the archive opened as a FILE */
  1139. X   int column;             /* column currently printing */
  1140. X   int state;              /* to keep track of how much of tag seen */
  1141. X   int inch;               /* char just read from archive */
  1142. X
  1143. X   static char usage1[] = "Fiz 1.0 (1987/01/30) public domain Zoo archive repair utility by Rahul Dhesi\n";
  1144. X   static char usage2[] = "Usage:  fiz archive[.zoo]  (\"fiz -h\" for help)\n";
  1145. X
  1146. X#ifdef SETBUF
  1147. X/* set stdout to unbuffered */
  1148. Xsetbuf (stdout, (char *) NULL);
  1149. X#endif
  1150. X
  1151. X   if (argc < 2) {
  1152. X      printf("%s%s", usage1, usage2);
  1153. X      exit (1);
  1154. X   }
  1155. X
  1156. X   if (strcmp(argv[1],"-h") == 0)
  1157. X      goto givehelp;
  1158. X
  1159. X   zooname = argv[1];
  1160. X
  1161. X   /* Add default extension if none supplied */
  1162. X   {
  1163. X      char *p, *q;
  1164. X      p = zooname + strlen(zooname);         /* point to last char */
  1165. X      while (p != zooname && *p != EXT_CH)
  1166. X         --p;
  1167. X      /* either found EXT_CH or reached beginning of zooname */
  1168. X      if (*p != EXT_CH) {
  1169. X         q = malloc(strlen(zooname) + strlen(EXT_DFLT) + 2);
  1170. X         if (q == NULL) {
  1171. X            printf("Fiz:  Ran out of memory.\n");
  1172. X            exit(1);
  1173. X         }
  1174. X         strcpy(q, zooname);
  1175. X         strcat(q, EXT_DFLT);
  1176. X         zooname = q;
  1177. X      }
  1178. X   }
  1179. X
  1180. X   zoo_file = fopen (zooname, FRDSTR);
  1181. X   if (zoo_file == NULL) {
  1182. X      printf("Fiz:  FATAL:  Could not open %s.\n", zooname);
  1183. X      exit(1);
  1184. X   }
  1185. X
  1186. X#define  NOTHING  1
  1187. X#define  CHAR_1   0xdc
  1188. X#define  CHAR_2   0xa7
  1189. X#define  CHAR_3   0xc4
  1190. X#define  CHAR_4   0xfd
  1191. X
  1192. X   column = 0;
  1193. X   state = NOTHING;
  1194. X   while ((inch = getc(zoo_file)) != EOF) {
  1195. X      inch = inch & 0xff;
  1196. X      if (state == NOTHING && inch == CHAR_1)
  1197. X         state = CHAR_1;
  1198. X      else if (state == CHAR_1 && inch == CHAR_2)
  1199. X         state = CHAR_2;
  1200. X      else if (state == CHAR_2 && inch == CHAR_3)
  1201. X         state = CHAR_3;
  1202. X      else if (state == CHAR_3 && inch == CHAR_4)
  1203. X         state = CHAR_4;
  1204. X      else
  1205. X         state = NOTHING;
  1206. X
  1207. X      if (state == CHAR_4) {           /* found tag */
  1208. X         long save_pos;
  1209. X         struct direntry direntry;
  1210. X         save_pos = ftell(zoo_file);
  1211. X         fseek(zoo_file, save_pos-4L, 0);          /* back to tag pos */
  1212. X         frd_dir(&direntry, zoo_file);             /* read dir entry */
  1213. X         printf("****************\n");
  1214. X
  1215. X         printf ("%8lu:  ", save_pos-4L);
  1216. X
  1217. X         if (direntry.dirlen > 0) {
  1218. X            printf ("[");
  1219. X            prtctrl (direntry.dirname);
  1220. X            printf ("]");
  1221. X         }
  1222. X
  1223. X         printf(" [");
  1224. X         prtctrl (direntry.fname);
  1225. X         printf ("]");
  1226. X
  1227. X         if (direntry.namlen > 0) {
  1228. X            printf (" [");
  1229. X            prtctrl (direntry.lfname);
  1230. X            printf ("]");
  1231. X         }
  1232. X         if (direntry.dir_crc != 0)
  1233. X            printf (" [*bad CRC*]");
  1234. X         printf ("\n");
  1235. X         fseek (zoo_file, save_pos, 0);         /* try again from there */
  1236. X      }
  1237. X   }
  1238. Xexit (0);      /* don't fall through */
  1239. X
  1240. Xgivehelp:
  1241. X
  1242. X   printf ("Fiz is used to help you recover data from a damaged archive.  Fiz\n");
  1243. X   printf ("searches the specified archive and prints the position (a decimal\n");
  1244. X   printf ("number) of each directory entry found and the directory name and\n");
  1245. X   printf ("filename associated with it.\n\n");
  1246. X
  1247. X   printf ("Make a record of the output of Fiz by redirecting it to a file.  Then\n");
  1248. X   printf ("use Zoo version 1.41 or higher to list or extract files in the\n");
  1249. X   printf ("damaged archives starting at a chosen position.  For example, you can\n");
  1250. X   printf ("start extracting files from archive \"badarc.zoo\" at position 1098\n");
  1251. X   printf ("with the command\n\n");
  1252. X
  1253. X   printf ("     zoo x@1098 badarc\n\n");
  1254. X
  1255. X   printf ("Zoo will ignore the first 1097 bytes of the damaged archive and you\n"); 
  1256. X   printf ("should be able to recover the undamaged files from the rest of the\n");
  1257. X   printf ("archive.\n\n");
  1258. X   printf ("The position supplied to Zoo should have been obtained from Fiz and\n");
  1259. X   printf ("must correspond to an undamaged directory entry in the archive.\n");
  1260. X
  1261. X   exit(1);
  1262. X}
  1263. X
  1264. X/*
  1265. Xprtctrl() prints a string with all unprintable characters converted
  1266. Xto printable form.  To avoid the program running astray trying to
  1267. Xprint damaged data, no more than MAXPRT characters are printed.
  1268. XCharacters with the 8th bit set are printed preceded with ~.  Control
  1269. Xcharacters are printed preceded with ^.  Both ~ and ^ may preced
  1270. Xthe character if a control character has the 8th bit set.
  1271. X*/
  1272. X#define  MAXPRT      50
  1273. X
  1274. Xvoid prtctrl (str)
  1275. Xchar *str;
  1276. X{
  1277. X   unsigned int ch;
  1278. X   int count;
  1279. X   count = 0;
  1280. X
  1281. X   while (count < MAXPRT && *str != '\0') {
  1282. X      ch = (unsigned) *str;
  1283. X      prtch(ch);
  1284. X      str++;
  1285. X      count++;
  1286. X   }
  1287. X}
  1288. X
  1289. X/*
  1290. XDoes the actual character printing for prtctrl()
  1291. X*/
  1292. Xvoid prtch(ch)
  1293. Xunsigned int ch;
  1294. X{
  1295. X   /* assumes ASCII character set */
  1296. X   if (ch < ' ') {                        /* ^@ through ^_ */
  1297. X      printf("^%c", ch + 0x40);
  1298. X   } else if (ch == 0x7f) {               /* DEL */
  1299. X      printf("^?");
  1300. X   } else if (ch > 0x7f) {                /* 8th bit set */
  1301. X      printf("~");                        /* .. so precede with ~ */
  1302. X      prtch(ch & 0x7f);                   /* slick recursive call */
  1303. X   } else
  1304. X      printf("%c", ch);                   /* plain char */
  1305. X}
  1306. SHAR_EOF
  1307. fi
  1308. if test -f 'generic.c'
  1309. then
  1310.     echo shar: "will not over-write existing file 'generic.c'"
  1311. else
  1312. sed 's/^X//' << \SHAR_EOF > 'generic.c'
  1313. X#ifndef LINT
  1314. Xstatic char genericid[]="@(#) generic.c 1.5 87/05/29 12:53:52";
  1315. X#endif /* LINT */
  1316. X
  1317. X/* Generic template for machine-dependent functions. */
  1318. X
  1319. X/****************
  1320. Xfunction trunc() truncates a file.
  1321. X*/
  1322. X
  1323. Xint trunc (handle)
  1324. Xint handle;
  1325. X{
  1326. X   /* code to truncate file goes here -- may be left empty */
  1327. X}
  1328. X
  1329. X/*****************
  1330. XFunction gettime() or getutime() gets the date and time of the file handle 
  1331. Xor filename supplied.  Date and time is in MSDOS format.
  1332. X*/
  1333. X#ifdef GETUTIME
  1334. Xgetutime (fname, date, time)
  1335. Xchar *fname;
  1336. X#else
  1337. Xgettime (handle,date,time)
  1338. Xint handle;
  1339. X#endif
  1340. Xint *date, *time;
  1341. X{
  1342. X   *date = *time = 0; /* not yet implemented */
  1343. X}
  1344. X
  1345. X/*****************
  1346. XFunction settime() or setutime() sets the date and time of the file handle
  1347. Xor filename supplied.  Date and time is in MSDOS format.
  1348. X*/
  1349. X#ifdef NIXTIME
  1350. Xint setutime(path,date,time)
  1351. Xchar *path;
  1352. X#else
  1353. Xint settime(handle, date, time)
  1354. Xint handle;
  1355. X#endif
  1356. Xunsigned int date, time;
  1357. X{
  1358. X   /* not yet implemented */
  1359. X}
  1360. X
  1361. X/*****************
  1362. XFunction mktemp() accepts a template of the form `baseXXXXXX' where
  1363. Xbase is an arbitrary string, and returns a unique temporary filename.
  1364. XIf template is not correct, it is returned unchanged.
  1365. X*/
  1366. Xchar *mktemp(template)
  1367. Xchar *template;
  1368. X{
  1369. X
  1370. X#ifndef NDEBUG
  1371. X   if (instr(template, "XXXXXX") == -1)
  1372. X      prterror ('w', "Incorrect template [%s] supplied to mktemp().\n",
  1373. X         template);
  1374. X#endif
  1375. X
  1376. X   strcpy(&template[instr(template, "XXXXXX")],"{zoo}.@@@");
  1377. X   return (template);
  1378. X}
  1379. X
  1380. X/*****************
  1381. XFunction isadir() or isuadir() returns 1 if supplied handle or 
  1382. Xfilename is a directory or other special file that should not be 
  1383. Xarchived, else it returns 0.
  1384. X*/
  1385. X
  1386. X#ifdef CHEKDIR
  1387. Xint isadir(han)
  1388. Xint han;
  1389. X{
  1390. X   return (0); /* by default assume never a directory */
  1391. X}
  1392. X#endif
  1393. X
  1394. X#ifdef CHEKUDIR
  1395. Xint isuadir(path)
  1396. Xchar *path;
  1397. X{
  1398. X   return (0); /* by default assume never a directory */
  1399. X}
  1400. X#endif
  1401. X
  1402. X/****************
  1403. XFunction fixfname() converts the supplied filename to a syntax
  1404. Xlegal for the host system.  It is used during extraction to make sure
  1405. Xthat a file can be extracted even if a badly-implemented archiver
  1406. Xstored it with an illegal filename.
  1407. X*/
  1408. X
  1409. Xchar *fixfname(fname)
  1410. Xchar *fname;
  1411. X{
  1412. X   return (fname); /* default is no-op */
  1413. X}
  1414. X
  1415. X/*****************
  1416. XFunction nextfile() is effectively a no-op.  Any wildcard expansion 
  1417. Xmust have been done before Zoo receives the arguments.
  1418. X*/
  1419. X
  1420. X#define FMAX 1
  1421. Xchar *nextfile (what, filespec, fileset)
  1422. Xint what;                        /* whether to initialize or match      */
  1423. Xregister char *filespec;         /* filespec to match if initializing   */
  1424. Xregister int fileset;            /* which set of files                  */
  1425. X{
  1426. X   static int first_time [FMAX+1];
  1427. X   static char saved_fspec [FMAX+1][PATHSIZE];  /* our own copy of filespec */
  1428. X
  1429. X   if (what == 0) {
  1430. X      strcpy (saved_fspec[fileset], filespec);  /* save the filespec */
  1431. X      first_time[fileset] = 1;
  1432. X      return (NULL);
  1433. X   }
  1434. X
  1435. X   if (first_time[fileset]) {
  1436. X      first_time[fileset] = 0;
  1437. X      return (saved_fspec[fileset]);
  1438. X   } else {
  1439. X      return (NULL);
  1440. X   }
  1441. X}
  1442. SHAR_EOF
  1443. fi
  1444. if test -f 'getfile.c'
  1445. then
  1446.     echo shar: "will not over-write existing file 'getfile.c'"
  1447. else
  1448. sed 's/^X//' << \SHAR_EOF > 'getfile.c'
  1449. X#ifndef LINT
  1450. Xstatic char sccsid[]="@(#) getfile.c 1.2 87/05/03 16:00:59";
  1451. X#endif /* LINT */
  1452. X
  1453. X/*
  1454. XCopyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
  1455. X*/
  1456. X
  1457. X#include "options.h"
  1458. X/* 
  1459. XThis function copies n characters from the source file to the destination
  1460. X
  1461. XInput:   output_han:    handle of destination file.
  1462. X         input_han:     handle of source file.
  1463. X         count:         count of characters to copy.
  1464. X         docrc:         0 if crc not wanted
  1465. X
  1466. XIf count is -1, copying is done until eof is encountered.
  1467. X
  1468. XThe source file is transferred to the current file pointer position in the
  1469. Xdestination file, using the handles provided.  Function return value is 0 
  1470. Xif no error, 2 if write error, and 3 if read error.  
  1471. X
  1472. XNote, however, that if the output handle is -2, it is taken to be the
  1473. Xnull device and no output actually occurs.  
  1474. X
  1475. XIf docrc is not 0, the global variable crccode is updated via addbfcrc().
  1476. XThis is done even if the output is to the null device.
  1477. X*/
  1478. X
  1479. X#include <stdio.h>
  1480. X#include "various.h"
  1481. X#include "zoofns.h"
  1482. X#include "zoomem.h"
  1483. X
  1484. Xint getfile(input_han, output_han, count, docrc)
  1485. Xint input_han, output_han;
  1486. Xlong count;
  1487. Xint docrc;
  1488. X{
  1489. X   register int how_much;
  1490. X
  1491. X   if (count == -1) {
  1492. X      while ((how_much = read (input_han, out_buf_adr, MEM_BLOCK_SIZE)) > 0) {
  1493. X         if (how_much == -1 || 
  1494. X               write (output_han, out_buf_adr, how_much) != how_much)
  1495. X            return (2);
  1496. X         if (docrc)
  1497. X            addbfcrc (out_buf_adr,how_much);
  1498. X      }
  1499. X      return (0);
  1500. X   }
  1501. X
  1502. X   while (count > 0) {
  1503. X      if (count > MEM_BLOCK_SIZE)
  1504. X         how_much = MEM_BLOCK_SIZE;
  1505. X      else
  1506. X         how_much = count;
  1507. X      count -= how_much;
  1508. X      if (read (input_han, out_buf_adr, how_much) != how_much)
  1509. X         return (3);
  1510. X      if (docrc)
  1511. X         addbfcrc (out_buf_adr, how_much);
  1512. X      if (output_han != -2)
  1513. X         if (write (output_han, out_buf_adr, how_much) != how_much)
  1514. X            return (2);
  1515. X   }
  1516. X   return (0);
  1517. X}
  1518. X
  1519. SHAR_EOF
  1520. fi
  1521. exit 0
  1522. #    End of shell archive
  1523. -- 
  1524. Rahul Dhesi         UUCP:  {ihnp4,seismo}!{iuvax,pur-ee}!bsu-cs!dhesi
  1525.  
  1526. -- 
  1527.  
  1528. Rich $alz
  1529. Cronus Project, BBN Labs            rsalz@bbn.com
  1530. Moderator, comp.sources.unix            sources@uunet.uu.net
  1531.